from __future__ import annotations

import os
import re
from typing import Set, Dict, Iterable, List

from .base import BaseLanguageDependencyStrategy


class ObjectiveCDependencyStrategy(BaseLanguageDependencyStrategy):
    LANGUAGE = 'objc'

    def __init__(self, logger=None):
        super().__init__(logger)
        self._import_patterns = [
            re.compile(r'^#import\s*[<"]([^>"]*)[">]', re.MULTILINE),
            re.compile(r'^#include\s*[<"]([^>"]*)[">]', re.MULTILINE),
            re.compile(r'^@import\s+([\w\.]+);', re.MULTILINE),
        ]
        self._header_search_paths: List[str] = []

    def extract_imports(self, content: str) -> Set[str]:
        imports: Set[str] = set()
        for pattern in self._import_patterns:
            imports.update(pattern.findall(content))
        return imports

    def resolve_import(
        self,
        import_name: str,
        source_file: str,
        module_to_files: Dict[str, Set[str]],
    ) -> Set[str]:
        resolved: Set[str] = set()
        source_dir = os.path.dirname(source_file)

        header_name = import_name
        if not header_name.endswith(('.h', '.hh', '.hpp')):
            header_name += '.h'

        search_paths = [
            source_dir,
            os.path.dirname(source_dir),
            os.path.join(source_dir, 'Headers'),
        ]

        search_paths.extend(self._header_search_paths)

        for path in search_paths:
            full_path = os.path.join(path, header_name)
            if os.path.exists(full_path):
                resolved.add(os.path.abspath(full_path))
                break

        return resolved

    def set_header_search_paths(self, paths: Iterable[str]):
        unique_paths: List[str] = []
        seen = set()
        for path in paths:
            resolved = os.path.abspath(path)
            if resolved not in seen and os.path.isdir(resolved):
                seen.add(resolved)
                unique_paths.append(resolved)
        self._header_search_paths = unique_paths
